package au.edu.unsw.editingtool.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.LinkedList;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import au.edu.unsw.editingtool.db.DBClaim;
import au.edu.unsw.editingtool.global.GlobalConstant;

/**
 * Servlet implementation class ClaimReview
 */
public class ClaimReview extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private String ServletContext = null;
	private String ApplicationContext = null;
	private String ApplicationPath = null;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public ClaimReview() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doService(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.doService(request, response);
	}
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext = getServletContext().getRealPath("") + GlobalConstant.fileSeparator;
		ApplicationContext = request.getLocalName()+":"+request.getServerPort()+"/"+
							GlobalConstant.APPLICATIONNAME+"/";
		ApplicationPath = request.getContextPath();
		System.out.println("==== [CLAIMREVIEW Servlet] ====");
		
		HttpSession session = request.getSession(false);
		String ctrlLast = (String) session.getAttribute(GlobalConstant.requestLastCommand);	
		System.out.println("[CLAIMREVIEW] requestLastCommand = "+ctrlLast);
		
		String querystring = request.getQueryString();
		if (querystring == null)
			querystring ="";
		if(querystring.compareTo("null")==0)
			querystring ="";
		
		String pid = null;
		pid = (String) request.getAttribute(GlobalConstant.pid);
		if (pid ==null)
			pid = request.getParameter(GlobalConstant.pid);
		
		String ctrl = null; 		
		if(request.getParameter(GlobalConstant.requestCommand)!=null)
		{
				ctrl = request.getParameter(GlobalConstant.requestCommand);
				System.out.println("[CLAIMREVIEW] Param requestCommand = "+ctrl);
		}
		
		if(request.getAttribute(GlobalConstant.requestCommand)!=null)
		{
			ctrl = (String) request.getAttribute(GlobalConstant.requestCommand);
			System.out.println("[CLAIMREVIEW] Attr requestCommand = "+ctrl);
		}
		if(ctrl==null)
			ctrl="";
		System.out.println("[CLAIMREVIEW] requestCommand = "+ctrl);		
		String username = (String) session.getAttribute(GlobalConstant.username);

		if(ctrl.compareTo(GlobalConstant.cmdClaimReview)==0)
		{	
			// Claim Request Section
			Hashtable<String,ArrayList<String>> lcr = new Hashtable<String,ArrayList<String>>();
			lcr=this.grabClaimRequest();	
			
			if(lcr.size()!=0)
			{
				Enumeration keys = lcr.keys();
				ArrayList<String> claimKeys = new ArrayList<String>();
				while (keys.hasMoreElements())
				{
					String key = (String) keys.nextElement();
					if(key==null)
						continue;
					if(key.length()==0)
						continue;
					claimKeys.add(key);
					
					
					ArrayList<String> claimPids = new ArrayList<String>();
					claimPids = (ArrayList<String>) lcr.get(key);
					if(claimPids==null)
						continue;
					if(claimPids.size()==0)
						continue;
					
					// DEBUG System.out.println("Key : "+key +" claimPids : "+claimPids.toString());
					request.setAttribute(GlobalConstant.paramClaimUserTemplate+key, claimPids);					
				}
				if(claimKeys.size()!=0)
					request.setAttribute(GlobalConstant.paramClaimClaimedAll,claimKeys);
			}
					
			//Search Section
			String claimSearchText = request.getParameter(GlobalConstant.paramClaimSearchText);
			String claimSearchType = request.getParameter(GlobalConstant.paramclaimSearchType);
			
			System.out.println("SearchText="+claimSearchText+" SearchType="+claimSearchType);
			
			if (claimSearchText!=null && claimSearchType!=null)
			{
				LinkedList<String[]> scr = new LinkedList<String[]>();
				if(claimSearchText.length()!=0)
				{
					if(claimSearchType.compareTo(GlobalConstant.paramClaimUsername)==0)
					{
						scr=this.searchResources(claimSearchText, null);
					}
					else if(claimSearchType.compareTo(GlobalConstant.paramClaimPid)==0)
					{
						scr=this.searchResources(null, claimSearchText);
					}
				}
				request.setAttribute(GlobalConstant.paramClaimAll, scr);
			}
			
			System.out.println("[CLAIMREVIEW] Forward to "+GlobalConstant.JSPClaimReview);
			session.setAttribute(GlobalConstant.requestLastCommand,GlobalConstant.cmdClaimReview);	
			RequestDispatcher rd = request.getRequestDispatcher(GlobalConstant.JSPClaimReview+"?"+querystring);
			rd.forward(request, response);
			return;
		}
		else if(ctrl.compareTo(GlobalConstant.cmdClaimReviewUpdate)==0)
		{
			Enumeration requestPids = request.getParameterNames();
			
			while(requestPids.hasMoreElements())
			{
				String requestPid = (String) requestPids.nextElement();				
				if(requestPid.startsWith(GlobalConstant.paramClaimPidTemplate))
				{
					String requestUsername = request.getParameter(requestPid);
					requestPid = requestPid.replace(GlobalConstant.paramClaimPidTemplate, "");
					requestPid = requestPid.replace('_', ':');										
					//DEBUG System.out.println("Username:"+requestUsername+" PID:"+requestPid);
					this.approveClaim(requestUsername,requestPid,username);
				}
			}								
			System.out.println("[CLAIMREVIEW] Forward to "+GlobalConstant.JSPClaimReviewSubmit);
			session.setAttribute(GlobalConstant.requestLastCommand,GlobalConstant.cmdClaimReviewUpdate);	
			RequestDispatcher rd = request.getRequestDispatcher(GlobalConstant.JSPClaimReviewSubmit+"?"+querystring);
			rd.forward(request, response);
			return;
		}
		else if(ctrl.compareTo(GlobalConstant.cmdClaimStatusUpdate)==0)
		{	
			String cpid = pid;
			String cusername = request.getParameter(GlobalConstant.username);
			String cstatus = request.getParameter(GlobalConstant.paramClaimStatus);
			
			if(cpid!=null && cusername!=null && cstatus!=null)
			{			
				this.updateStatus(cusername, cpid, cstatus, username);
				session.setAttribute(GlobalConstant.requestLastCommand,GlobalConstant.cmdClaimStatusUpdate);
				System.out.println("[CLAIMREVIEW] Last Command "+GlobalConstant.cmdClaimStatusUpdate);
				PrintWriter out = response.getWriter();
				out.println("Update status="+cstatus+" for resource="+cpid+" with username="+cusername);
				return;
			}
			else
			{
				System.out.println("[CLAIMREVIEW] Error on "+GlobalConstant.cmdClaimStatusUpdate);
				PrintWriter out = response.getWriter();
				out.println("Error on "+GlobalConstant.cmdClaimStatusUpdate);
				return;
			}
		}
		else if(ctrl.compareTo(GlobalConstant.cmdClaimDelete)==0)
		{	
			String cpid = pid;
			String cusername = request.getParameter(GlobalConstant.username);
			
			if(cpid!=null && cusername!=null)
			{			
				this.deleteClaim(cusername ,cpid);
				session.setAttribute(GlobalConstant.requestLastCommand,GlobalConstant.cmdClaimDelete);
				System.out.println("[CLAIMREVIEW] Last Command "+GlobalConstant.cmdClaimDelete);
				PrintWriter out = response.getWriter();
				out.println("Delete resource="+cpid+" with username="+cusername);
				return;
			}
			else
			{
				System.out.println("[CLAIMREVIEW] Error on "+GlobalConstant.cmdClaimDelete);
				PrintWriter out = response.getWriter();
				out.println("ERROR: ["+GlobalConstant.cmdClaimDelete+"] no pid or user found!");
				return;
			}
		}
		else
		{
			System.out.println("[CLAIMREVIEW] Forward to "+GlobalConstant.JSPError);			
			session.setAttribute(GlobalConstant.responseType,GlobalConstant.typeError);
			session.setAttribute(GlobalConstant.responseControl,GlobalConstant.cmdClaimReview);
			session.setAttribute(GlobalConstant.responseMsg, "Error on CLAIMREVIEW Servlet!");
			session.setAttribute(GlobalConstant.requestLastCommand,GlobalConstant.cmdClaimReview);
			RequestDispatcher rd = request.getRequestDispatcher(GlobalConstant.JSPError);
			rd.forward(request, response);
			return;
		}
	}
	
	private Hashtable<String,ArrayList<String>> grabClaimClaimed()
	{
		DBClaim dbclaim = new DBClaim();
		dbclaim.setConfFile(ServletContext + GlobalConstant.configFilePath);
		
		Hashtable<String,ArrayList<String>> al = new Hashtable<String,ArrayList<String>>();
		try
		{
			al = dbclaim.getResources(GlobalConstant.claimClaimed);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}		
		return al;
	}
	
	private Hashtable<String,ArrayList<String>> grabClaimRequest()
	{
		DBClaim dbclaim = new DBClaim();
		dbclaim.setConfFile(ServletContext + GlobalConstant.configFilePath);
		
		Hashtable<String,ArrayList<String>> al = new Hashtable<String,ArrayList<String>>();
		try
		{
			al = dbclaim.getResources(GlobalConstant.claimRequest);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}		
		return al;
	}
	
	private Hashtable<String,ArrayList<String>> grabClaim(String username, String pid)
	{
		DBClaim dbclaim = new DBClaim();
		dbclaim.setConfFile(ServletContext + GlobalConstant.configFilePath);
		
		Hashtable<String,ArrayList<String>> al = new Hashtable<String,ArrayList<String>>();
		try
		{
			al = dbclaim.getResources(GlobalConstant.claimRequest);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}		
		return al;
	}
	
	private LinkedList<String[]> searchResources(String username, String pid)
	{
		DBClaim dbclaim = new DBClaim();
		dbclaim.setConfFile(ServletContext + GlobalConstant.configFilePath);
		LinkedList<String[]> result= new LinkedList<String[]>();
		if(username!=null)
		{
			if (username.length()==0)
				username=null;
		}
		
		if(pid!=null)
		{
			if (pid.length()==0)
				pid=null;
		}
		
		try
		{
			result = dbclaim.searchResources(username,pid);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}		
		return result;
	}
	
	private void approveClaim(String username, String pid,String reviewer)
	{
		if(username==null || username.length()==0 || pid==null || pid.length()==0 || reviewer==null || reviewer.length()==0 )
			return;
		DBClaim dbclaim = new DBClaim();
		dbclaim.setConfFile(ServletContext + GlobalConstant.configFilePath);
		
		try {
			dbclaim.setClaimStatus(username,pid,GlobalConstant.claimClaimed,reviewer,"Claim Approved");
		} 
		catch (Exception e) {			
			e.printStackTrace();
		}						
	}
	
	private void updateStatus(String username, String pid, String status, String reviewer)
	{
		if(username==null || username.length()==0 || pid==null || pid.length()==0 || reviewer==null || reviewer.length()==0||status==null || status.length()==0)
			return;
		DBClaim dbclaim = new DBClaim();
		dbclaim.setConfFile(ServletContext + GlobalConstant.configFilePath);
		
		try {
			if(status.compareTo(GlobalConstant.claimRequest)==0)
				dbclaim.setClaimStatus(username,pid,status,reviewer,"Claim set to request");
			else
				dbclaim.setClaimStatus(username,pid,status,reviewer,"Claim Approved");
		} 
		catch (Exception e) {			
			e.printStackTrace();
		}						
	}
	
	private void deleteClaim(String username ,String pid)
	{
		if(username==null || username.length()==0 || pid==null || pid.length()==0)
			return;
		DBClaim dbclaim = new DBClaim();
		dbclaim.setConfFile(ServletContext + GlobalConstant.configFilePath);
		try {
			dbclaim.deleteClaim(username,pid);
		} 
		catch (Exception e) {			
			e.printStackTrace();
		}						
	}
}
